
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    console.log("content.js接收消息", message);
    //第一次开始发送
    if (message.cmd === 'save_send_info') {
        let items = $(".item-3mHhwr.item-3XjbnG");
        if (!items.eq(1).hasClass("selected-g-kMVV")) {
            sendResponse({ code: 1, msg: "请切换至所有好友列表！" });
            return
        }
        try {
            sendResponse({ code: 0, msg: 'ok' });
            setStorage(message).then(() => {
                return processClick(message.target, "list");
            })
        } catch (error) {
            notifi(error.message);
            alert(error.message);
            return
        }
    } else if (message.cmd === 'zanting') {
        sendResponse({ code: 0, msg: 'ok' });
        setStorage({ taskStatus: 2 });
        clearTimeout(sleepTimeout);
    } else if (message.cmd === 'cancel') {
        sendResponse({ code: 0, msg: 'ok' });
        chrome.storage.local.set({
            taskStatus: 0,
            user_id: null,
            height: 0,
            targetvalues: [],
            target: null,
            captchaCount: 0
        });
    } else if (message.cmd === 'send_message') {
        sendResponse({ code: 0, msg: 'ok' });//直接回调切换按钮状态，后续错误后续提示
        let items = $(".item-3mHhwr.item-3XjbnG");
        if (items.length == 0 || !items.eq(1).hasClass("selected-g-kMVV")) {
            alert("请切换至所有好友列表后开始！");
            return
        }
        getStorage('target').then(target => {
            return setStorage({ taskStatus: 1 }).then(() => {
                return target;
            });//暂停后开始 保存状态
        }).then((target) => {
            // return process(target);
            return processClick(target, message.url);
        }).catch(error => {
            console.log(">>>", error);
            notifi('私信异常\n打开好友列表重试！');
            alert('私信异常\n打开好友列表重试！');
        });
    }
    return true;
})

//数字正则
const reg = /[1-9][0-9]*/g;
//发送逻辑处理过程 第二种方式 点击进入详情发送
async function processClick(target, url, height, user_id, targetvalues) {
    let taskStatus = await getStorage('taskStatus');
    if (taskStatus !== 1) {
        return
    }
    // 切换url监听
    if (url === 'single') {
        let slp = Math.random() * 10 + 10;
        console.log('sleep', slp);
        await sleep(slp * 1000);
        taskStatus = await getStorage('taskStatus');
        if (taskStatus !== 1) {
            return
        }
        // let user_id = await getStorage('user_id');
        let res = await dmchannel(user_id);
        let channelId = res.id;
        console.log("获取聊天频道", res);
        res = await dm(res.id);
        console.log('发送私信😃', res);
        if (res.captcha_key) {
            console.log('发送出现验证码，挑战验证码😫');
            let user_agent = await getStorage('user_agent');
            try {
                let brk = false;
                while (!brk) {
                    let captchRes = await capSolver(res.captcha_sitekey, res.captcha_rqdata, 'https://discord.com', user_agent);
                    res = await dm(channelId, captchRes, res.captcha_rqtoken);
                    console.log('发送私信挑战验证码结果：', res);
                    if (res.captcha_key) {
                        let captchaCount = await getStorage('captchaCount');
                        captchaCount++
                        setStorage({ captchaCount });
                        if (captchaCount >= 3) {
                            setStorage({ taskStatus: 2 });
                            brk = true;
                            alert(`
                            未解决验证码，任务已自动暂停
                            请按如下步骤操作：
                            1.在输入框输入消息并发送
                            2.弹出验证码后手动解决
                            3.点击继续任务`);
                            return
                        }
                    } else {
                        setStorage({ captchaCount: 0 });
                        break
                    }
                    await sleep(5 * 1000);
                }
            } catch (error) {
                setStorage({ taskStatus: 2 });
                alert("验证码识别失败")
                return
            }
        }
        await setStorage({ height, user_id, targetvalues });
        await sleep(1500);
        window.history.back();
        processClick(target, 'list');
    } else {
        //列表点击
        let height = await getStorage('height');
        if (!height) {
            height = 0;
        }
        if (target === 'in') {
            $(".peopleList-2VBrVI.auto-2K3UW5.scrollerBase-_bVAAt").scrollTop(height);
            let slp = Math.random() * 10 + 10;
            console.log('sleep', slp);
            await sleep(slp * 1000);
            taskStatus = await getStorage('taskStatus');
            if (taskStatus !== 1) {
                return
            }
            let targetvalues = await getStorage('targetvalues');
            let currentPageUsers = $('.peopleListItem-u6dGxF');
            for (let index = 0; index < currentPageUsers.length; index++) {
                const element = currentPageUsers[index];
                let nickname = $(element).find(".username-3JLfHz.username-Qpc78p").html();
                let usernum = $(element).find(".discriminator-WV5K5s").html();
                console.log(nickname, usernum);
                if (targetvalues.includes(nickname + usernum)) {
                    let user_id = $(element).data("list-item-id");
                    user_id = user_id.match(reg)[0];
                    $(element).click();
                    targetvalues = targetvalues.filter((item) => {
                        return item !== nickname + usernum;
                    });
                    processClick(target, 'single', height, user_id, targetvalues);
                    return
                }
            }
            let all_user_num = 0;
            let all_user = $(".title-x4dI75.container-q97qHp").html();
            all_user_num = all_user.match(reg)[0];
            all_user_num = Number(all_user_num);
            if (targetvalues.length <= 0 || height / 62 > all_user_num) {
                setStorage({
                    taskStatus: 0,
                    user_id: null,
                    height: 0,
                    targetvalues: [],
                    captchaCount: 0
                });
                let msg = '已发送全部私信';
                if (targetvalues.length > 0) {
                    msg += `\n部分好友无法自动发送，请手动发送:\n${targetvalues.toString()}`
                }
                notifi(msg);
                chrome.runtime.sendMessage(
                    {
                        cmd: "alert",
                        message: msg,
                    }, (message) => {
                        console.log("alert完成");
                    }
                )
                return
            }
            height += 62 * 7;//currentPageUsers长度每次不一样，有可能会跳过中间一部分，还是按照固定大小一点点遍历
            setStorage({ height });
            processClick(target, 'list', height, user_id);
        } else if (target === 'all') {
            let user_id = await getStorage('user_id');
            let next;
            if (!user_id) {
                user_id = $(".peopleListItem-u6dGxF").eq(0).data("list-item-id");//格式：people-list___975665794186874920或people___975665794186874920
                user_id = user_id.match(reg)[0];
                next = $(".peopleListItem-u6dGxF").eq(0);
            } else {
                $(".peopleList-2VBrVI.auto-2K3UW5.scrollerBase-_bVAAt").scrollTop(height);
                let slp = Math.random() * 10 + 10;
                console.log('sleep', slp);
                await sleep(slp * 1000);
                taskStatus = await getStorage('taskStatus');
                if (taskStatus !== 1) {
                    return
                }
                next = $(`[data-list-item-id$=${user_id}]`).next();
                if (next.length == 0) {
                    setStorage({ taskStatus: 2 });
                    notifi('私信异常\n打开好友列表重试！');
                    alert('私信异常\n打开好友列表重试！');
                    return
                }
                user_id = next.data("list-item-id");
                user_id = user_id.match(reg)[0];
            }
            if (!user_id) {
                setStorage({ taskStatus: 2 });
                notifi('私信异常\n打开好友列表重试！');
                alert('私信异常\n打开好友列表重试！');
                return
            }
            console.log('user_id', user_id);
            let all_user_num = 0;
            let all_user = $(".title-x4dI75.container-q97qHp").html();
            all_user_num = all_user.match(reg)[0];
            all_user_num = Number(all_user_num);
            height += 62;
            console.log("遍历个数：", height / 62);
            if (height / 62 >= all_user_num) {
                setStorage({ taskStatus: 0 });
                notifi('已发送全部私信');
                alert('已发送全部私信');
                return
            }
            console.log("需发送用户：", all_user_num);
            next.click();
            processClick(target, 'single', height, user_id);
        }
    }
}

//发送逻辑处理过程
async function process(target) {
    try {
        let all_user = $(".title-x4dI75.container-q97qHp").html();
        let all_user_num = all_user.match(reg)[0];
        console.log("共有用户：", all_user_num);
        all_user_num = Number(all_user_num);
        await setStorage({ all_user_num });
        let user_id = await getStorage('user_id');
        if (!user_id) {
            user_id = $(".peopleListItem-u6dGxF").eq(0).data("list-item-id");
        }
        await setStorage({ user_id });
        //信息存储后开始发送
        let height = await getStorage('height');
        if (!height) {
            height = 0;
        }
        for (let index = 0; index < all_user_num; index++) {
            let taskStatus = await getStorage('taskStatus');
            if (taskStatus !== 1) {
                throw new Error('任务未开始！');
            }
            $(".peopleList-2VBrVI.auto-2K3UW5.scrollerBase-_bVAAt").scrollTop(height);
            let slp = Math.random() * 10 + 10;
            console.log('sleep', slp);
            await sleep(slp * 1000);
            let next = $(`[data-list-item-id$=${user_id}]`).next();
            let user_id = next.data("list-item-id");
            console.log(index, user_id);//people-list___988783478705385494
            user_id = user_id.substring(14);
            //白名单
            if (target === 'in') {
                let targetvalues = await getStorage('values');
                let nickname = next.find(".username-3JLfHz.username-Qpc78p").html();
                let usernum = next.find(".discriminator-WV5K5s").html();
                console.log(nickname, usernum);
                if (!targetvalues.includes(nickname)) {
                    //skip
                    height += 62;
                    await setStorage({ height, user_id });
                    continue
                }
            }
            //获取聊天频道
            let res = await dmchannel(user_id);
            console.log(res);
            res = await dm(res.id);
            //返回异常，停止任务，提示用户
            // if (res) {
            //     throw new Error('验证码')
            // }
            height += 62;
            await setStorage({ height: height, user_id });
        }
    } catch (error) {
        setStorage({ taskStatus: 2 });
        throw new Error(error.message);
    }
}

//获取频道
async function dmchannel(user_id) {
    try {
        let cookies = await getStorage("cookies");
        // let cookieStr = "";
        // for (let index = 0; index < cookies.length; index++) {
        //     const element = cookies[index];
        //     cookieStr += `${element.name}=${element.value};`
        // }
        let authorization = await getStorage("authorization");
        let x_super_properties = await getStorage("x_super_properties");
        let dmurl = `https://discord.com/api/v9/users/@me/channels`;
        console.log(dmurl);
        const res = await fetch(dmurl, {
            body: JSON.stringify({ recipients: [user_id] }),
            credentials: 'include',
            headers: {
                "content-type": " application/json",
                "accept": "*/*",
                "accept-encoding": "gzip, deflate, br",
                "accept-language": "zh-CN,zh;q=0.9",
                "authorization": authorization,
                "cookie": cookies,
                "referer": "https://discord.com/channels/@me",
                "sec-ch-ua": `"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"`,
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "macOS",
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-origin",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
                "x-debug-options": "bugReporterEnabled",
                "x-discord-locale": "en-US",
                "x-super-properties": x_super_properties,
            },
            method: "POST",
        }).then(res => {
            return res.json();
        }).then(data => {
            return data;
        })
        return res;
    } catch (error) {
        console.log(error);
        throw new Error(error.message);
    }
}

//发私信
async function dm(user_id, cap_key, rq_token) {
    try {
        let cookies = await getStorage("cookies");
        // let cookieStr = "";
        // for (let index = 0; index < cookies.length; index++) {
        //     const element = cookies[index];
        //     cookieStr += `${element.name}=${element.value};`
        // }
        let authorization = await getStorage("authorization");
        let x_super_properties = await getStorage("x_super_properties");
        let content = await getStorage("content");
        if (content == "") {
            return
        }
        let tempSnowflake = new Snowflake(1, 1, 0);
        let nonce = tempSnowflake.nextId();
        // let dmurl = `${message.url}`;
        // dmurl = dmurl.substring(33);
        dmurl = user_id;//函数参数传入ID
        dmurl = `https://discord.com/api/v9/channels/${dmurl}/messages`;
        let body = {
            content: content,
            nonce: nonce,
            tts: false
        }
        if (cap_key) {
            body.captcha_key = cap_key;
            body.captcha_rqtoken = rq_token;
        }
        const res = await fetch(dmurl, {
            body: JSON.stringify(body),
            credentials: 'include',
            headers: {
                "content-type": " application/json",
                "accept": "*/*",
                "accept-encoding": "gzip, deflate, br",
                "accept-language": "zh-CN,zh;q=0.9",
                "authorization": authorization,
                "cookie": cookies,
                "referer": `https://discord.com/channels/@me/${user_id}`,
                "sec-ch-ua": `"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"`,
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "macOS",
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-origin",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
                "x-debug-options": "bugReporterEnabled",
                "x-discord-locale": "en-US",
                "x-super-properties": x_super_properties,
            },
            method: "POST",
        }).then(res => {
            return res.json();
        }).then(data => {
            return data;
        })
        return res;
    } catch (error) {
        console.log(error);
        throw new Error(error.message);
    }
}
async function getStorage(key) {
    return new Promise((resolve, reject) => {
        chrome.storage.local.get([key], function (result) {
            if (result[key] === undefined) {
                console.log(`获取storege:${key}失败`);
                resolve(null);
            } else {
                resolve(result[key]);
            }
        });
    });
};

async function setStorage(values) {
    return new Promise((resolve, reject) => {
        chrome.storage.local.set(values, function () {
            console.log('保存成功', values);
            resolve();
        });
    });
};

let sleepTimeout;
function sleep(time) {
    return new Promise((resolve) => {
        sleepTimeout = setTimeout(resolve, time)
    });
}

function client_uuid(preuuid) {
    let a = Uint8Array.from(atob(preuuid), c => c.charCodeAt(0))
    a[20] = a[20] + 1
    // let base64String = btoa(String.fromCharCode.apply(null, a));
    return ArrayBufferToBase64(a);
}
//a.toString('base64')
function ArrayBufferToBase64(buffer) {
    //第一步，将ArrayBuffer转为二进制字符串
    let binary = '';
    let bytes = new Uint8Array(buffer);
    for (let len = bytes.byteLength, i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    //将二进制字符串转为base64字符串
    return window.btoa(binary);
}

// let a  =  Uint8Array.from(atob("RoACfgfcnA3+JbUeIZ6F74QBAAANAAAA"), c => c.charCodeAt(0))
// a[20] = a[20]+1
// //a.toString('base64')
// function ArrayBufferToBase64(buffer) {
//     //第一步，将ArrayBuffer转为二进制字符串
// 	let binary = '';
// 	let bytes = new Uint8Array(buffer);
// 	for (let len = bytes.byteLength, i = 0; i < len; i++) {
// 		binary += String.fromCharCode(bytes[i]);
// 	}
//     //将二进制字符串转为base64字符串
// 	return window.btoa(binary);
// }
// ArrayBufferToBase64(a)

// 获取当前选项卡ID
function getCurrentTabId(callback) {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        if (callback) callback(tabs.length ? tabs[0].id : null);
    });
}
// 向content-script主动发送消息
function sendMessageToContentScript(message, callback) {
    getCurrentTabId((tabId) => {
        chrome.tabs.sendMessage(tabId, message, function (response) {
            if (callback) callback(response);
        });
    });
}

//桌面通知
function notifi(message) {
    chrome.runtime.sendMessage(
        {
            cmd: "notification",
            message: message,
        }, (message) => {
            console.log("桌面通知完成");
        }
    )
}

//识别验证码
async function capSolver(sitekey, rqdata, site, ua) {
    let cturl = "https://api.capsolver.com/createTask";
    let proxy = await getStorage('proxy');
    if (!proxy) {
        alert('未设置代理，无法自动识别验证码');
        return
    }
    let proxy_key = await getStorage('proxy_key');
    let url = new URL(proxy);
    let ctreq = {
        clientKey: proxy_key,//apikey
        task: {
            type: "HCaptchaTask",
            websiteURL: site,
            websiteKey: sitekey,
            proxyType: url.protocol.replace(":", ""),
            proxyAddress: url.hostname,
            proxyPort: Number(url.port),
            proxyLogin: url.username,
            proxyPassword: url.password,
            userAgent: ua,
            isInvisible: true,
            isEnterprise: true,
            enterprisePayload: {
                rqdata: rqdata
            }
        },
    }
    let ctrsp = await fetch(cturl, {
        method: "POST",
        body: JSON.stringify(ctreq)
    }).then(res => {
        return res.json();
    })
    let grreq = {
        clientKey: proxy_key,
        taskId: ctrsp.taskId,
    }
    let grurl = "https://api.capsolver.com/getTaskResult"
    now = Date.now();
    await sleep(10 * 1000);//10秒
    let brk = false;
    setTimeout(() => {
        brk = true;
    }, 1000 * 60);
    while (!brk) {
        if (brk) {
            return
        }
        let grrsp = await fetch(grurl, {
            method: "POST",
            body: JSON.stringify(grreq)
        }).then(res => {
            return res.json();
        })
        if (grrsp.status == "ready") {
            return grrsp.solution.gRecaptchaResponse
        }
        await sleep(5 * 1000);
    }
}